﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;

namespace holysheng.FileX
{
    // 文件属性基类，包含文件名、文件路径、后缀名的属性
    public class FileAttributes
    {
        private string _fileOnlyPath;
        private string _fileOnlyName;
        private string _fileOnlyExtName;

        // 文件名
        public string FileOnlyName { get { return _fileOnlyName; } set { _fileOnlyName = value; } }

        // 文件路径
        public string FileOnlyPath { get { return _fileOnlyPath; } set { _fileOnlyPath = value; } }

        // 后缀名
        public string FileOnlyExtName { get { return _fileOnlyExtName; } set { _fileOnlyExtName = value; } }

        // 分割全文件名，得到文件名、扩展名、路径
        public void GetFileAttributes(string fileAllName)
        {
            Conver.ConverFileNameToString.GetFileStr(fileAllName, out _fileOnlyPath, out _fileOnlyName, out _fileOnlyExtName);
        }
    }

    // 快捷方式基类
    public class ShortcutAttributes : FileAttributes
    {
        // 目标文件，即带扩展名+路径的文件名，如C:\新建文本文档.txt，右键快捷方式的目标（T）
        public string TargetPath { get; set; }

        // 起始位置，文件路径，如C:\，右键快捷方式的起始位置（S）
        public string WorkingDirectory { get; set; }

        // 运行方式，1=常规窗口，2=最小化，3=最大化，右键快捷方式的运行方式（R）
        public int WindowStyle { get; set; }

        // 备注，鼠标放在图标上提示改文字，右键快捷方式的备注（O）
        public string Description { get; set; }

        // 快捷方式的图标
        public string IconLocation { get; set; }

        // 得到快捷方式全部属性
        public new void GetFileAttributes(string fileAllName)
        {
            base.GetFileAttributes(fileAllName);
            ReadShortcut(fileAllName);
        }

        /// <summary>
        /// 引用COM组件 Windows Script Host Object Model
        /// using IWshRuntimeLibrary;
        /// 为某个文件创建快捷方式
        /// </summary>
        /// <param name="fileAllName">源目标文件全路径</param>
        /// <param name="newDirectory">快捷方式存放的路径</param>
        /// <param name="shortcutName">要创建的快捷方式名称，无需加.lnk后缀（</param>
        public void CreateShortcuts(string fileAllName, string newDirectory, string shortcutName)
        {
            string _fileOnlyPath;
            string _fileOnlyName;
            string _fileOnlyExtName;

            Conver.ConverFileNameToString.GetFileStr(fileAllName, out _fileOnlyPath, out _fileOnlyName, out _fileOnlyExtName);
            FileOnlyPath = _fileOnlyPath;
            FileOnlyName = _fileOnlyName;
            FileOnlyExtName = _fileOnlyExtName;
            WorkingDirectory = FileOnlyPath;
            TargetPath = fileAllName;

            //创建快捷方式的步骤
            shortcutName += ".lnk"; // 添加后缀
            try
            {
                IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
                IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(newDirectory + shortcutName); // 创建快捷方式对象
                shortcut.TargetPath = fileAllName; // 设置目标
                shortcut.WorkingDirectory = WorkingDirectory; // 设置起始位置
                shortcut.WindowStyle = 1; // 设置运行方式
                                          // shortcut.Description = ""; // 设置备注
                                          // shortcut.IconLocation = ""; // 设置图标路径
                shortcut.Save(); // 保存快捷方式
            }
            catch (Exception ex)
            {
                Debug.WriteLine("发生错误，代码为：" + ex.ToString());
            }
        }

        /// <summary>
        /// 修改快捷方式属性
        /// </summary>
        /// <param name="fileAllName">源目标文件全路径<</param>
        /// <param name="newTargetPath">新目标文件</param>
        /// <param name="newWorkingDirectory">新起始位置</param>
        /// <param name="newWindowStyle">新运行方式</param>
        /// <param name="newDescription">新备注</param>
        /// <param name="newIconLocation">新图标</param>
        public bool EditShortcuts(string fileAllName, string newTargetPath, string newWorkingDirectory, int newWindowStyle, string newDescription, string newIconLocation)
        {
            try
            {
                IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
                IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(fileAllName); // 获取快捷方式对象
                shortcut.TargetPath = newTargetPath;
                shortcut.WorkingDirectory = newWorkingDirectory;
                shortcut.WindowStyle = newWindowStyle;
                shortcut.Description = newDescription;
                shortcut.IconLocation = newIconLocation;
                shortcut.Save();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("发生错误，代码为：" + ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 修改快捷方式属性
        /// </summary>
        /// <param name="fileAllName">源目标文件全路径<</param>
        /// <param name="newTargetPath">新目标文件</param>
        /// <param name="newWorkingDirectory">新起始位置</param>
        public bool EditShortcuts(string fileAllName, string newTargetPath, string newWorkingDirectory)
        {
            IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
            IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(fileAllName); // 获取快捷方式对象
            try
            {
                shortcut.TargetPath = newTargetPath;
                shortcut.WorkingDirectory = newWorkingDirectory;
                shortcut.Save();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("保存错误，替换的目录为：" + newTargetPath + "，错误代码为：" + ex.ToString());
                return false;
            }
        }

        // 读取快捷方式信息
        public void ReadShortcut(string fileAllName)
        {
            IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
            IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(fileAllName); // 获取快捷方式对象
            try
            {
                TargetPath = shortcut.TargetPath; // 目标信息，即带扩展名+路径的文件名
                WorkingDirectory = shortcut.WorkingDirectory; // 起始位置信息，文件路径
                if (WorkingDirectory != null && WorkingDirectory != "") // 此处要判断起始位置是否为空，因为有些快捷方式可能失效，不判断会造成异常
                {
                    if (WorkingDirectory.Substring(WorkingDirectory.Length - 1, 1) != "\\") // 如果路径最后一次字符不等于\，则自动加\
                    {
                        WorkingDirectory += "\\";
                    }
                }
                WindowStyle = shortcut.WindowStyle; // 运行方式信息
                Description = shortcut.Description; // 备注信息
                IconLocation = shortcut.IconLocation; // 图标信息
            }
            catch (Exception ex)
            {
                Debug.WriteLine("发生错误，错误的文件为：" + shortcut.TargetPath + "   代码为：" + ex.ToString());
            }
        }

        // 删除快捷方式
        public bool DelShortcuts(string fileAllName)
        {
            if (System.IO.File.Exists(fileAllName))
            {
                System.IO.File.Delete(fileAllName);
                return true;
            }
            return false;
        }
    }

    // 文件操作类
    public class FileControl
    {
        BindingList<FileAttributes> _fileList = new BindingList<FileAttributes>();

        // 通过路径和扩展名，遍历文件夹下的文件集合
        public BindingList<FileAttributes> GetFileList(string path, string fileExtension)
        {
            _fileList.Clear(); // 此方法可能多次被调用，所以每次调用都应清空原数据
            return ErgodicPathToGetFiles(path, fileExtension);
        }

        // 遍历文件夹，参数为路径、扩展名，得到文件夹下的文件集合
        internal BindingList<FileAttributes> ErgodicPathToGetFiles(string path, string fileExtension)
        {
            RecursivePath(path, fileExtension, ref _fileList, true); // 递归调用
            return _fileList;
        }

        // 内部类：递归函数，返回文件属性集合，参数为路径、扩展名、集合、是否递归
        internal BindingList<FileAttributes> RecursivePath(string path, string fileExtension, ref BindingList<FileAttributes> filelist, bool isRecursive)
        {
            try
            {
                DirectoryInfo theDir = new DirectoryInfo(path);
                FileInfo[] files = theDir.GetFiles(); // 得到当前目录下所有文件
                FileAttributes f;
                foreach (FileInfo file in files)
                {
                    string fileAllName = file.FullName;
                    if (fileAllName.EndsWith(fileExtension)) // 判断文件后缀
                    {
                        f = new FileAttributes();
                        f.GetFileAttributes(fileAllName);// 得到所有属性
                        filelist.Add(f);
                    }
                }

                if (isRecursive) // 是否获取子文件夹内的文件列表，递归遍历
                {
                    DirectoryInfo[] dirs = theDir.GetDirectories(); // 得到文件夹列表
                    foreach (DirectoryInfo dir in dirs)
                    {
                        RecursivePath(dir.FullName, fileExtension, ref filelist, true);
                    }
                }
                return filelist;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("递归错误：" + ex.ToString());
                return null;
            }
        }
    }

    // 快捷方式操作类
    public class ShortcutControl
    {
        BindingList<ShortcutAttributes> _fileList = new BindingList<ShortcutAttributes>();
        string fileExtension = ".lnk";
        // 通过路径和扩展名，遍历文件夹下的文件集合
        public BindingList<ShortcutAttributes> GetFileList(string path)
        {
            _fileList.Clear(); // 此方法可能多次被调用，所以每次调用都应清空原数据
            return ErgodicPathToGetFiles(path, fileExtension); // 其它调用方法加上后缀名参数，方便今后代码复用
        }

        // 遍历文件夹，参数为路径、扩展名，得到文件夹下的文件集合
        internal BindingList<ShortcutAttributes> ErgodicPathToGetFiles(string path, string fileExtension)
        {

            RecursivePath(path, fileExtension, ref _fileList, true); // 递归调用
            return _fileList;
        }

        // 内部类：递归函数，返回文件属性集合，参数为路径、扩展名、集合、是否递归
        internal BindingList<ShortcutAttributes> RecursivePath(string path, string fileExtension, ref BindingList<ShortcutAttributes> filelist, bool isRecursive)
        {
            try
            {
                DirectoryInfo theDir = new DirectoryInfo(path);
                FileInfo[] files = theDir.GetFiles(); // 得到当前目录下所有文件
                ShortcutAttributes f;
                foreach (FileInfo file in files)
                {
                    string fileAllName = file.FullName;
                    if (fileAllName.EndsWith(fileExtension)) // 判断文件后缀
                    {
                        f = new ShortcutAttributes();
                        f.GetFileAttributes(fileAllName);// 得到所有属性
                        filelist.Add(f);
                    }
                }

                if (isRecursive) // 是否获取子文件夹内的文件列表，递归遍历
                {
                    DirectoryInfo[] dirs = theDir.GetDirectories(); // 得到文件夹列表
                    foreach (DirectoryInfo dir in dirs)
                    {
                        RecursivePath(dir.FullName, fileExtension, ref filelist, true);
                    }
                }
                return filelist;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("递归错误：" + ex.ToString());
                return null;
            }
        }
    }
}
